<template>
  <a-form ref="formRef"
          autocomplete="off"
          :model="formData"
          :layout="layout"
          :rules="rules"
          :label-col="{span: 8}"
          :wrapper-col="{span: 16}"
          :labelAlign="labelAlign"
          class="form">
    <template v-for="(item, index) in formList"
              :key="index">
      <a-form-item v-if="!item.hide"
                   :name="item.prop">
        <template v-slot:label>
          <span>
            {{ item.name}}
            <a-tooltip v-if="item.tooltip"
                       :title="item.tooltip">
              <QuestionCircleOutlined />
            </a-tooltip>
          </span>
        </template>
        <template v-if="item.select">
          <!-- 单项选择器
            {
              select: true,
              name: '',
              prop: '',
              options: [{value: any, label: ''}, ...]
            } -->
          <a-select v-model:value="formData[item.prop]"
                    allow-clear
                    option-label-prop="label"
                    :disabled="disabled || item.disabled"
                    :getPopupContainer="(triggerNode) => triggerNode.parentNode"
                    :options="item.options"
                    :placeholder="`请选择${item.name}`"
                    :style="{width: labelWidth + 'px'}" />
        </template>
        <template v-else-if="item.cascader">
          <!-- 级联选择器
            {
              cascader: true,
              name: '',
              prop: '',
              options: [{value: any, label: '', children: []}, ...]
            } -->
          <div v-if="item.disabled"
               :style="{width: labelWidth + 'px'}">
            {{formData.dataPath}}
          </div>
          <a-cascader v-else
                      v-model:value="formData[item.prop]"
                      allow-clear
                      change-on-select
                      option-label-prop="label"
                      :getPopupContainer="(triggerNode) => triggerNode.parentNode"
                      :disabled="disabled"
                      :loadData="item.loadData"
                      :options="item.options"
                      :placeholder="`请选择${item.name}`"
                      :style="{width: labelWidth + 'px'}" />
        </template>
        <template v-else-if="item.date">
          <!-- 日期选择器
            {
              date: true,
              name: '',
              props: ['', '']
            } -->
          <a-date-picker v-model:value="formData[item.prop]"
                         value-format="x"
                         :disabled="disabled || item.disabled"
                         :placeholder="`请选择${item.name}`"
                         :showTime="item.showTime || false"
                         :style="{width: labelWidth + 'px'}" />
        </template>
        <template v-else-if="item.switch">
          <!-- 开关
            {
              switch: true,
              name: '',
              prop: '',
              options: [],
            } -->
          <a-switch v-model:checked="formData[item.prop]"
                    checked-children="是"
                    un-checked-children="否"
                    :disabled="disabled || item.disabled"></a-switch>
        </template>
        <template v-else-if="item.number">
          <a-input-number v-model:value.trim="formData[item.prop]"
                          :disabled="disabled || item.disabled"
                          :min="item.min"
                          :max="item.max"
                          :placeholder="`请输入${item.name}`"
                          :style="{width: labelWidth + 'px'}"></a-input-number>
        </template>
        <template v-else-if="item.textarea">
          <a-textarea v-model:value="formData[item.prop]"
                      :autosize="{minRows: 3}"
                      :disabled="disabled || item.disabled"
                      :placeholder="`请输入${item.name}`"
                      style="width: 600px"></a-textarea>
        </template>
        <!-- 可输入的选择框
          {
              autoComplete: true,
              name: '',
              prop: '',
              value: '',
          } -->
        <template v-else-if="item.autoComplete">
          <a-auto-complete v-model:value.trim="formData[item.prop]"
                           :options="item.options"
                           :placeholder="`请输入${item.name}`"
                           :style="{width: labelWidth + 'px'}">
          </a-auto-complete>
        </template>
        <template v-else>
          <!-- 文本输入框 -->
          <a-input v-model:value.trim="formData[item.prop]"
                   allow-clear
                   :disabled="disabled || item.disabled"
                   :placeholder="`请输入${item.name}`"
                   :style="{width: labelWidth + 'px'}" />
        </template>
      </a-form-item>
    </template>
  </a-form>
  <div class="form-btn">
    <a-button @click="handleReset">取消</a-button>
    <a-button type="primary"
              @click="handleSubmit">确定</a-button>
  </div>
</template>

<script lang="ts">
import { defineComponent, PropType, reactive, ref } from 'vue';
import { FormItem } from './types/searchItem';

import { QuestionCircleOutlined } from '@ant-design/icons-vue';

export default defineComponent({
  components: { QuestionCircleOutlined },

  props: {
    // 表单列表项
    formList: {
      type: Array as PropType<FormItem[]>,
      default: () => [],
    },
    // 表单 key, value 值
    formData: {
      type: Object,
      default: {},
    },
    layout: {
      type: String,
      default: 'inline',
    },
    labelAlign: {
      type: String,
      default: 'left',
    },
    // 自自定义校验规则
    rules: {
      type: Object,
      default: {},
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // label宽度
    labelWidth: {
      type: Number,
      default: 280,
    },
  },

  emits: ['handle-submit', 'handle-reset'],

  setup(props, { emit }) {
    const formRef = ref();
    let formData = reactive(props.formData);

    const handleSubmit = () => {
      formRef.value.validate().then(() => {
        emit('handle-submit', formData);
      });
    };

    const handleReset = () => {
      formRef.value.resetFields();
      emit('handle-reset');
    };

    return {
      formRef,
      formData,
      handleReset,
      handleSubmit,
    };
  },
});
</script>

<style lang="less" scoped>
.form {
  .ant-form-item {
    margin: 0 20px 30px 0;

    :deep(.ant-form-item-label) {
      min-width: 100px;
      text-align: right;
    }
  }
}

.form-btn {
  text-align: right;

  .ant-btn {
    margin-left: 20px;
  }
}
</style>
